package in.iqing.view.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import butterknife.Bind;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
import butterknife.OnTouch;
import in.iqing.app.R;
import in.iqing.base.BaseActivity;
import in.iqing.control.api.ApiHelper;
import in.iqing.control.api.callback.VolumeCallback;
import in.iqing.control.helper.LogHelper;
import in.iqing.control.util.ConvertUtil;
import in.iqing.control.util.IntentUtil;
import in.iqing.control.util.MiscUtil;
import in.iqing.control.util.ToastUtil;
import in.iqing.model.bean.Book;
import in.iqing.model.bean.Chapter;
import in.iqing.model.bean.DirectoryItem;
import in.iqing.model.bean.History;
import in.iqing.model.bean.Page;
import in.iqing.model.bean.Paragraph;
import in.iqing.model.bean.Volume;
import in.iqing.model.db.DBHelper;
import in.iqing.model.sp.SettingSP;
import in.iqing.module.content.QingPageContainer;
import in.iqing.module.data.DataHelper;
import in.iqing.module.download.ChapterTask;
import in.iqing.module.download.ContentTask;
import in.iqing.view.dialog.ContentMenuDialog;

/**
 * Created by neavo on 2014/6/24.
 */

public class ContentActivity extends BaseActivity {

    @Bind(R.id.title_text)
    public TextView titleText;

    @Bind(R.id.net_text)
    public TextView netText;

    @Bind(R.id.page_text)
    public TextView pageText;

    @Bind(R.id.time_text)
    public TextView timeText;

    @Bind(R.id.battery_text)
    public TextView batteryText;

    @Bind(R.id.battery_image)
    public ImageView batteryImage;

    @Bind(R.id.page_container)
    public QingPageContainer pageContainer;

    @Bind(R.id.widget_content_menu_top)
    public View widgetTopMenu;

    @Bind(R.id.widget_content_menu_bottom)
    public View widgetBottomMenu;

    @Bind(R.id.widget_content_progress)
    public View widgetProgress;

    @Bind(R.id.progress_percent_text)
    public TextView progressPercentText;

    @Bind(R.id.progress_title_text)
    public TextView progressTitleText;

    @Bind(R.id.progress_seek_bar)
    public SeekBar progressSeekbar;

    @Bind(R.id.widget_content_color)
    public View widgetColor;

    @Bind(R.id.night_mode_radio_group)
    public RadioGroup nightModeRadioGroup;

    @Bind(R.id.radio_day)
    public RadioButton radioButtonDay;

    @Bind(R.id.radio_night)
    public RadioButton radioButtonNight;

    @Bind(R.id.widget_content_setting)
    public View widgetSetting;

    @Bind(R.id.brightness_seekbar)
    public SeekBar brightnessSeekbar;

    @Bind(R.id.use_system_brightness_checkbox)
    public CheckBox useSystemBrightness;

    @Bind(R.id.set_screen_on_checkbox)
    public CheckBox alwaysOnCheckbox;

    @Bind(R.id.convert_traditional_checkbox)
    public CheckBox traditionalCheckbox;

    @Bind(R.id.text_size_small)
    public CheckedTextView smallText;

    @Bind(R.id.text_size_normal)
    public CheckedTextView normalText;

    @Bind(R.id.text_size_large)
    public CheckedTextView largeText;

    @Bind(R.id.text_size_ex_large)
    public CheckedTextView exlargeText;

//    @Bind(R.id.menu_layer)
//    public View menuLayer;

    private Chapter chapter;
    private List<Chapter> chapters;

    private String battery;
    private BatteryBroadcastReceiver batteryReceiver;

    private boolean backToFront;
    private boolean frontToBack;

    private boolean fromBookStart;
    private boolean fromBookmark;
    private boolean fromLatestUpdate;
    private boolean fromChapter;

    private boolean alwayson;
    private boolean nightmode;
    private boolean traditional;

    private boolean showingMenu;
    private boolean showingProgress;
    private boolean showingColor;
    private boolean showingSetting;


    private long lastPrevChapterPress;
    private long lastNextChapterPress;

    private float brightness;

    private SimpleDateFormat dateFormat;

    private List<Paragraph> paragraphs;

    private Book book;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_content);
    }

    @Override
    protected void onInitialize(Bundle savedInstanceState) {
        super.onInitialize(savedInstanceState);
        initVariables();
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        resetIntent();
        setAlwaysOn();
        setNightMode();
        loadBook();
    }

    @Override
    protected void onResume() {
        super.onResume();

        registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    }

    @Override
    protected void onPause() {
        super.onPause();
        saveBookmark();
        unregisterReceiver(batteryReceiver);
    }

    @Override
    public boolean dispatchKeyEvent(@NonNull KeyEvent ev) {
        boolean isConsumed;

        int action = ev.getAction();
        int keyCode = ev.getKeyCode();

        if (action == KeyEvent.ACTION_DOWN) {
            if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
                processPrevClick();
            } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
                processNextClick();
            }
        }

        isConsumed = (action == KeyEvent.ACTION_UP || action == KeyEvent.ACTION_DOWN) &&
                (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN);

        return isConsumed || super.dispatchKeyEvent(ev);
    }

    @OnTouch(R.id.page_container)
    public boolean onPageContainerTouch(MotionEvent ev) {
        return pageContainer.onTouchEvent(ev);
    }

    private void initVariables() {
        this.dateFormat = new SimpleDateFormat("HH:mm");
        this.batteryReceiver = new BatteryBroadcastReceiver();
        this.backToFront = getIntent().getExtras().getBoolean("back_to_front");
        this.frontToBack = getIntent().getExtras().getBoolean("front_to_back");
        this.chapter = (Chapter) getIntent().getExtras().getSerializable("chapter");
        this.chapters = (List<Chapter>) getIntent().getExtras().getSerializable("chapters");
        this.book = (Book) getIntent().getSerializableExtra("book");
        this.alwayson = SettingSP.getSingleton(getContext()).getAlwaysOn();
        this.nightmode = SettingSP.getSingleton(getContext()).getNightMode();
        this.traditional = SettingSP.getSingleton(getContext()).getTraditional();
        this.fromBookmark = getIntent().getBooleanExtra("from_bookmark", false);
        this.fromChapter = getIntent().getBooleanExtra("from_chapter", false);
        this.fromBookStart = getIntent().getBooleanExtra("from_book_start", false);
        this.fromLatestUpdate = getIntent().getBooleanExtra("from_latest_update", false);
        progressSeekbar.setOnSeekBarChangeListener(new ProgressSeekbarListener());
        nightModeRadioGroup.setOnCheckedChangeListener(new NightModeChangeListener());
        alwaysOnCheckbox.setChecked(alwayson);
        traditionalCheckbox.setChecked(traditional);
        setupBrightness();
        setTextSize();
    }

    private void resetIntent() {
        Bundle extras = getIntent().getExtras();
        extras.putBoolean("back_to_front", false);
        extras.putBoolean("front_to_back", false);
        extras.putBoolean("fromcontent", false);
        getIntent().putExtras(extras);
    }

    private void setAlwaysOn() {
        if (alwayson) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        } else {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }
    }

    private void setupBrightness() {
        boolean isSystemBrightness = SettingSP.getSingleton(getContext()).isUseSystemBrightness();
        if (isSystemBrightness) {
            useSystemBrightness();
            // store brightness when first load
            if (SettingSP.getSingleton(getContext()).getBrightness() == 0) {
                SettingSP.getSingleton(getContext()).setBrightness(brightness);
            }
        } else {
            useCustomBrightness();
        }
        brightnessSeekbar.setMax(255);
        brightnessSeekbar.setProgress((int) brightness);
        brightnessSeekbar.setEnabled(!isSystemBrightness);
        useSystemBrightness.setChecked(isSystemBrightness);
        brightnessSeekbar.setOnSeekBarChangeListener(new BrightnessSeekbarListener());
    }

    private void setTextSize() {
        smallText.setChecked(false);
        normalText.setChecked(false);
        largeText.setChecked(false);
        exlargeText.setChecked(false);
        switch (SettingSP.getSingleton(getContext()).getSize()) {
            case SettingSP.TEXT_SIZE_SMALL:
                smallText.setChecked(true);
                break;
            case SettingSP.TEXT_SIZE_NORMAL:
                normalText.setChecked(true);
                break;
            case SettingSP.TEXT_SIZE_LARGE:
                largeText.setChecked(true);
                break;
            case SettingSP.TEXT_SIZE_EXLARGE:
                exlargeText.setChecked(true);
                break;
            default:
                normalText.setChecked(true);
                break;
        }
    }

    private void changeScreenBrightness(int value) {
        if (value <= 1) {
            value = 1;
        }
        if (value > 255) {
            value = 255;
        }
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.screenBrightness = value / 255f;
        getWindow().setAttributes(lp);
    }

    private void setNightMode() {
        netText.setTextColor(getResources().getColor(nightmode
                        ? R.color.content_night_info
                        : R.color.content_day_info)
        );

        pageText.setTextColor(getResources().getColor(nightmode
                        ? R.color.content_night_info
                        : R.color.content_day_info)
        );

        timeText.setTextColor(getResources().getColor(nightmode
                        ? R.color.content_night_info
                        : R.color.content_day_info)
        );

        titleText.setTextColor(getResources().getColor(nightmode
                        ? R.color.content_night_info
                        : R.color.content_day_info)
        );

        batteryText.setTextColor(getResources().getColor(nightmode
                        ? R.color.content_night_info
                        : R.color.content_day_info)
        );

        batteryImage.setImageResource(nightmode
                        ? R.drawable.icon_battery_night
                        : R.drawable.icon_battery_day
        );

        getWindow().getDecorView().setBackgroundResource(nightmode
                ? R.drawable.content_night_bg
                : R.drawable.content_day_bg);

        radioButtonNight.setChecked(nightmode);
        radioButtonDay.setChecked(!nightmode);
    }

    private void setProgress() {
        progressPercentText.setText(String.valueOf(NumberFormat.getPercentInstance().format(getIndexPercent())));
        progressTitleText.setText(chapter.getTitle());
        progressSeekbar.setProgress((int) (getIndexPercent() * 100));
    }

    private void loadBook() {
        if (fromChapter) {
            loadParagraphs();
        } else if (fromBookStart || fromBookmark || fromLatestUpdate) {
            loadDirectory();
        }
    }

    private void loadDirectory() {
        ApiHelper.getSingleton().getVolume(VOLLEY_TAG, book.getId(), new ExtQingVolumeCallback());
    }

    private void loadParagraphs() {
        ChapterTask chapterTask = DBHelper.getInstance().getChapterTask(chapter);
        if (chapterTask != null &&
                chapterTask.getFinishCount() == chapterTask.getTotalCount()) {
            ContentTask stringTask = DBHelper.getInstance().getStringContent(chapter);
            if (stringTask == null) {
                loadOnLineContent();
            } else {
                try {
                    LogHelper.warn(TAG, "load local content");
                    String content = FileUtils.readFileToString(new File(stringTask.getSavePath()));
                    List<Paragraph> paragraphs = JSON.parseArray(content, Paragraph.class);
                    ContentActivity.this.paragraphs = paragraphs;
                    pageContainer.preparedAsync(chapter, paragraphs, new PageContainerCallback());
                } catch (IOException e) {
                    e.printStackTrace();
                    loadOnLineContent();
                }
            }
        } else {
            loadOnLineContent();
        }
    }

    private void loadOnLineContent() {
        LogHelper.warn(TAG, "load online content");
        DataHelper.getSingleton().getParagraphs(chapter, new LoadParagraphsTaskCallback());
    }

    private void processInfo() {
        titleText.setText(ConvertUtil.convert(
                chapter.getTitle(),
                traditional
        ));

        netText.setText(ConvertUtil.convert(
                MiscUtil.getNetType(getContext()),
                traditional
        ));

        timeText.setText(ConvertUtil.convert(
                dateFormat.format(new Date(System.currentTimeMillis())),
                traditional
        ));

        pageText.setText(String.valueOf(NumberFormat.getPercentInstance().format(getIndexPercent())));
        batteryText.setText(String.valueOf(battery));

        setProgress();
    }

    private void switchPrevChapter() {
        int i = 0;
        for (; i < chapters.size(); i++) {
            if (chapters.get(i).getId() == chapter.getId()) {
                break;
            }
        }

        if (i > 0) {
            backToFront = true;
            frontToBack = false;
            chapter = chapters.get(i - 1);
            loadParagraphs();
        } else {
            ToastUtil.show(getContext(), R.string.activity_content_first_chapter);
        }
    }

    private void switchNextChapter() {
        int i = 0;
        for (; i < chapters.size(); i++) {
            if (chapters.get(i).getId() == chapter.getId()) {
                break;
            }
        }

        if (i < chapters.size() - 1) {
            backToFront = false;
            frontToBack = true;
            chapter = chapters.get(i + 1);
            loadParagraphs();
        } else {
            ToastUtil.show(getContext(), R.string.activity_content_last_chapter);
        }
    }

    private void processPrevClick() {
        if (!pageContainer.isPrepared() || showingMenu || showingProgress || showingColor || showingSetting) {
            return;
        }

        int i = pageContainer.getIndex();

        if (i > 0) {
            pageContainer.setIndex(i - 1);
        } else if (SystemClock.elapsedRealtime() - lastPrevChapterPress < 2000) {
            switchPrevChapter();
        } else {
            lastPrevChapterPress = SystemClock.elapsedRealtime();
            ToastUtil.show(getContext(), R.string.activity_content_switch_volume);
        }
    }

    private void processNextClick() {
        if (!pageContainer.isPrepared() || showingMenu || showingProgress || showingColor || showingSetting) {
            return;
        }

        int i = pageContainer.getIndex();

        if (i < pageContainer.getSize() - 1) {
            pageContainer.setIndex(i + 1);
        } else if (SystemClock.elapsedRealtime() - lastNextChapterPress < 2000) {
            switchNextChapter();
        } else {
            lastNextChapterPress = SystemClock.elapsedRealtime();
            ToastUtil.show(getContext(), R.string.activity_content_switch_volume);
        }
    }

    private void processCenterClick() {
        if(pageContainer.getCurrPage().getType() == Page.TYPE_ILLUSTRATION ){
            goIllustration();
            return;
        }

        if (showingMenu | showingProgress | showingColor | showingSetting) {
            hideAllMenus();
        } else {
            setMenusShowing(true);
        }
    }

    private void setMenusShowing(boolean show) {
        widgetTopMenu.setVisibility(show ? View.VISIBLE : View.GONE);
        widgetBottomMenu.setVisibility(show ? View.VISIBLE : View.GONE);
        showingMenu = show;
        pageContainer.setScrollEnabled(!show);
    }

    private void setProgressShowing(boolean show) {
        widgetProgress.setVisibility(show ? View.VISIBLE : View.GONE);
        showingProgress = show;
        pageContainer.setScrollEnabled(!show);
    }

    private void setColorShowing(boolean show) {
        widgetColor.setVisibility(show ? View.VISIBLE : View.GONE);
        showingColor = show;
        pageContainer.setScrollEnabled(!show);
    }

    private void setSettingShowing(boolean show) {
        widgetSetting.setVisibility(show ? View.VISIBLE : View.GONE);
        showingSetting = show;
        pageContainer.setScrollEnabled(!show);
    }

    private void hideAllMenus(){
        widgetTopMenu.setVisibility(View.GONE);
        widgetBottomMenu.setVisibility(View.GONE);
        widgetProgress.setVisibility(View.GONE);
        widgetColor.setVisibility(View.GONE);
        widgetSetting.setVisibility(View.GONE);
        showingMenu = showingProgress = showingColor = showingSetting = false;
        pageContainer.setScrollEnabled(true);
    }


    @OnClick(R.id.progress_layout)
    public void onProgressMenuClick(View v) {
        setMenusShowing(false);
        setProgressShowing(true);
        setProgress();
    }

    @OnClick(R.id.color_layout)
    public void onColorMenuClick(View v) {
        setMenusShowing(false);
        setColorShowing(true);
    }

    @OnClick(R.id.setting_layout)
    public void onSettingMenuClick(View v) {
        setMenusShowing(false);
        setSettingShowing(true);
    }

    @OnClick(R.id.previous_chapter)
    public void onPreviousChapterClick(View v) {
        switchPrevChapter();
    }

    @OnClick(R.id.next_chapter)
    public void onNextChapterClick(View v) {
        switchNextChapter();
    }

    @OnClick(R.id.back)
    public void onBackClick(View v) {
        finish();
    }

    public void goIllustration() {
        Bundle extras = getIntent().getExtras();
        extras.putSerializable("page", pageContainer.getCurrPage());

        IntentUtil.startActivity(getActivity(), IllustrationActivity.class, extras);
    }

    @OnCheckedChanged(R.id.use_system_brightness_checkbox)
    public void onUseSystemBrightnessCheckChanged(CompoundButton buttonView, boolean isChecked) {
        boolean isSystemBrightness = isChecked;
        SettingSP.getSingleton(getContext()).setUseSystemBrightness(isSystemBrightness);
        if (isSystemBrightness) {
            useSystemBrightness();
        } else {
            useCustomBrightness();
        }
        brightnessSeekbar.setProgress((int) brightness);
        brightnessSeekbar.setEnabled(!isSystemBrightness);
    }

    @OnCheckedChanged(R.id.use_system_brightness_checkbox)
    public void onAlwaysOnChanged(CompoundButton buttonView, boolean isChecked) {
        alwayson = isChecked;
        SettingSP.getSingleton(getContext()).setAlwaysOn(alwayson);
        setAlwaysOn();
    }

    @OnCheckedChanged(R.id.convert_traditional_checkbox)
    public void onUseTraditionalChanged(CompoundButton buttonView, boolean isChecked) {
        traditional = isChecked;
        SettingSP.getSingleton(getContext()).setTraditional(traditional);
        saveBookmark();
        if (paragraphs != null && paragraphs.size() > 0) {
            pageContainer.preparedAsync(chapter, paragraphs, new PageContainerCallback());
        }
    }

    @OnClick(R.id.text_size_small)
    public void onSmallTextClick(View v) {
        if (!smallText.isChecked()) {
            SettingSP.getSingleton(getContext()).setSize(SettingSP.TEXT_SIZE_SMALL);
            setTextSize();
            saveBookmark();
            if (paragraphs != null && paragraphs.size() > 0) {
                pageContainer.preparedAsync(chapter, paragraphs, new PageContainerCallback());
            }
        }

    }

    @OnClick(R.id.text_size_normal)
    public void onNormalTextClick(View v) {
        if (!normalText.isChecked()) {
            SettingSP.getSingleton(getContext()).setSize(SettingSP.TEXT_SIZE_NORMAL);
            setTextSize();
            saveBookmark();
            if (paragraphs != null && paragraphs.size() > 0) {
                pageContainer.preparedAsync(chapter, paragraphs, new PageContainerCallback());
            }
        }
    }

    @OnClick(R.id.text_size_large)
    public void onLargeTextClick(View v) {
        if (!largeText.isChecked()) {
            SettingSP.getSingleton(getContext()).setSize(SettingSP.TEXT_SIZE_LARGE);
            setTextSize();
            saveBookmark();
            if (paragraphs != null && paragraphs.size() > 0) {
                pageContainer.preparedAsync(chapter, paragraphs, new PageContainerCallback());
            }
        }
    }

    @OnClick(R.id.text_size_ex_large)
    public void onExlargeTextClick(View v) {
        if (!smallText.isChecked()) {
            SettingSP.getSingleton(getContext()).setSize(SettingSP.TEXT_SIZE_EXLARGE);
            setTextSize();
            saveBookmark();
            if (paragraphs != null && paragraphs.size() > 0) {
                pageContainer.preparedAsync(chapter, paragraphs, new PageContainerCallback());
            }
        }
    }

    private void useSystemBrightness() {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        brightness = lp.screenBrightness * 255;
        try {
            brightness = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        changeScreenBrightness((int) brightness);
    }

    private void useCustomBrightness() {
        brightness = SettingSP.getSingleton(getContext()).getBrightness();
        changeScreenBrightness((int) brightness);
    }

    private float getIndexPercent() {
        return (float) (pageContainer.getIndex() + 1) / (float) (pageContainer.getSize());
    }

    private void seekToPage(float percent) {
        pageContainer.setIndex((int) (pageContainer.getSize() * percent));
    }

    private void saveBookmark() {
        if (pageContainer.isPrepared()) {
            long bookmark = pageContainer.getCurrPage().getStart();
            DBHelper.getInstance().setBookmark(book.getId(), chapter.getId(), bookmark);
        }
    }

    private class LoadParagraphsTaskCallback implements DataHelper.GetQingParagraphCallback {

        @Override
        public void onStart() {
            showLoading();
        }

        @Override
        public void onFinish(List<Paragraph> paragraphs) {
            if (paragraphs.size() == 0) {
                showEmpty();
            } else {
                ContentActivity.this.paragraphs = paragraphs;
                pageContainer.preparedAsync(chapter, paragraphs, new PageContainerCallback());
            }
        }
    }

    private class BatteryBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
                battery = String.valueOf(
                        intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100)
                );
            }
        }
    }

    private class PageContainerCallback implements QingPageContainer.ICallback {

        @Override
        public void onPrepared() {
            showContent();

            int index = 1;
            History bookmark = DBHelper.getInstance().getBookmark(book.getId());
            if (bookmark == null || bookmark.getChapterId() != chapter.getId()) {
                saveBookmark();
            } else {
                for (int i = 0; i < pageContainer.getPages().size(); i++) {
                    if (bookmark.getBookmark() >= pageContainer.getPages().get(i).getStart()
                            && bookmark.getBookmark() < pageContainer.getPages().get(i).getEnd()) {
                        index = i + 1;
                    }
                }
            }
            LogHelper.warn(TAG, "load index:" + index);
            if (backToFront) {
                index = pageContainer.getSize();
            } else if (frontToBack) {
                index = 0;
            }

            if (index > 0) {
                index = index - 1;
            }

            pageContainer.setIndex(index, true);
//            getWindow().getDecorView().setBackgroundDrawable(null);
            processInfo();
        }

        @Override
        public void onPageChanged() {
            processInfo();
            saveBookmark();
        }

        @Override
        public void onPrevClick() {
            processPrevClick();
        }

        @Override
        public void onNextClick() {
            processNextClick();
        }

        @Override
        public void onCenterClick() {
            processCenterClick();
        }
    }

    private class ProgressSeekbarListener implements SeekBar.OnSeekBarChangeListener {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                progressPercentText.setText(String.valueOf(NumberFormat.getPercentInstance().format((float) progress / 100f)));
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            seekToPage((float) seekBar.getProgress() / 100f);
        }
    }

    private class NightModeChangeListener implements RadioGroup.OnCheckedChangeListener {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            switch (checkedId) {
                case R.id.radio_day:
                    nightmode = false;
                    break;
                case R.id.radio_night:
                    nightmode = true;
                    break;
            }
            SettingSP.getSingleton(getContext()).setNightMode(nightmode);
            setNightMode();
            pageContainer.invalidateNightmode();
        }
    }

    private class BrightnessSeekbarListener implements SeekBar.OnSeekBarChangeListener {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                brightness = progress;
                changeScreenBrightness((int) brightness);
                SettingSP.getSingleton(getContext()).setBrightness(brightness);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    }

    private class ExtQingVolumeCallback extends VolumeCallback {

        @Override
        public void onStart() {
            showLoading();
        }

        @Override
        public void onSuccess(List<Volume> volumes) {
            if (volumes == EMPTY) {
                showEmpty();
                return;
            }

            List<DirectoryItem> directoryItems = new ArrayList<>();
            chapters = new ArrayList<>();
            for (Volume volume : volumes) {
                directoryItems.add(DirectoryItem.fromVolume(volume));
                if (volume.getChapters() != null && volume.getChapters().size() > 0) {
                    for (Chapter chapter : volume.getChapters()) {
                        directoryItems.add(DirectoryItem.fromChapter(chapter));
                        chapters.add(chapter);
                    }
                }
            }

            if (fromBookStart) {
                chapter = chapters.get(0);
            } else if (fromBookmark) {
                // set default load chapter
                ContentActivity.this.chapter = chapters.get(0);
                History bookmark = DBHelper.getInstance().getBookmark(book.getId());
                for (Chapter chapter : chapters) {
                    if (chapter.getId() == bookmark.getChapterId()) {
                        ContentActivity.this.chapter = chapter;
                    }
                }
            } else if (fromLatestUpdate) {
                ContentActivity.this.chapter = chapters.get(0);
                for (Chapter chapter : chapters) {
                    if (chapter.getId() == book.getLastChapterId()) {
                        ContentActivity.this.chapter = chapter;
                    }
                }
            } else {
                // default load from start
                ContentActivity.this.chapter = chapters.get(0);
            }
            loadParagraphs();
        }

        @Override
        public void onFailure(int code, String msg) {
            showEmpty();
        }
    }

    private class ContentMenuDialogCallback implements ContentMenuDialog.ICallback {

        @Override
        public void onSettingClick() {
            Bundle extras = getIntent().getExtras();
            extras.putBoolean("fromcontent", true);

            finish();
            IntentUtil.startActivity(getActivity(), SettingActivity.class, extras);
        }

        @Override
        public void onIllustrationClick() {
            Bundle extras = getIntent().getExtras();
            extras.putSerializable("page", pageContainer.getCurrPage());

            IntentUtil.startActivity(getActivity(), IllustrationActivity.class, extras);
        }

        @Override
        public void onProgressSeekBarChanged(int i) {
            pageContainer.setIndex(i);
        }
    }
}